package com.vmj.classfile;

import com.vmj.Command;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * Created by yangshoujun on 2017/8/5 下午8:15.
 */
public class BootstrapClassLoader implements ClassLoader {

    private Command command;

    public BootstrapClassLoader(Command cmd) {
        this.command = cmd;
    }

    public byte[] loadClass(String className) throws IOException {
        String jh = command.getJavaHome();
        String jreLibPath = jh.endsWith("/") ? jh.concat("jre/lib") : jh.concat("/jre/lib");
        File jreLibDir = new File(jreLibPath);
        File[] files = jreLibDir.listFiles();
        if(files.length == 0) {
            return null;
        }

        String classFile = className.replace('.', File.separatorChar) + ".class";
        for(File file : files) {
            if(!isZip(file)) {
                continue;
            }
            ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
            ZipEntry entry = null;
            while( (entry = zis.getNextEntry()) != null) {
                if(entry.isDirectory()) {
                    continue;
                }

                if(!entry.getName().endsWith(".class")) {
                    continue;
                }

                if(entry.getName().equals(classFile)) {
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    byte buffer[] = new byte[1024];
                    int read = 0;
                    while((read = zis.read(buffer, 0, buffer.length)) != -1) {
                        bos.write(buffer, 0, read);
                    }
                    return bos.toByteArray();
                }
            }
        }
        return null;
    }

    private boolean isZip(File file) {
        if(file.isFile() && (file.getName().toUpperCase().endsWith(".JAR")
                || file.getName().toUpperCase().endsWith(".ZIP"))) {
            return true;
        }
        return false;
    }
}
